package sg.edu.nus.iss.vmcs.customer;

import java.util.Iterator;

import sg.edu.nus.iss.vmcs.store.CashStore;
import sg.edu.nus.iss.vmcs.store.CashStoreItem;
import sg.edu.nus.iss.vmcs.store.Coin;
import sg.edu.nus.iss.vmcs.store.Store;
import sg.edu.nus.iss.vmcs.store.StoreController;
import sg.edu.nus.iss.vmcs.system.MainController;
import sg.edu.nus.iss.vmcs.util.LabelledDisplay;
import sg.edu.nus.iss.vmcs.util.VMCSException;
import sg.edu.nus.iss.vmcs.util.WarningDisplay;

public class ChangeGiver {

	private TransactionController tCtrl;

	public ChangeGiver(TransactionController tCtrl) {
		this.tCtrl = tCtrl;
	}

	public TransactionController getTransactionController() {
		return tCtrl;
	}

	public void displayChangeStatus() {
		MainController mCtrl = tCtrl.getMainController();
		StoreController sCtrl = mCtrl.getStoreController();
		Integer totalCash = sCtrl.getTotalCash();

		CustomerPanel custPanel = tCtrl.getCustomerPanel();
		WarningDisplay wrnDisplay = custPanel.getNoChangeDisplay();
		wrnDisplay.setState(totalCash <= 0);
	}

	public boolean giveChange(int change_required) {
		if (change_required == 0)
			return true;

		Boolean change_available = true;
		Integer change = change_required;

		// Get the Cashstore
		CashStore cashstore = (CashStore) tCtrl.getMainController()
				.getStoreController().getStore(Store.CASH);
		int len = cashstore.getStoreSize();

		// Check every denomination starting from biggest value
		//Iterator Pattern
		Iterator it=cashstore.createIterator(CashStore.DESCENDING);
		while(it.hasNext()){
		//for (int i = (len - 1); i >= 0; i--) {

			// Get the denomination
			//Iterator Pattern
			CashStoreItem store_item = (CashStoreItem)it.next();
			//CashStoreItem store_item = (CashStoreItem) cashstore
			//		.getStoreItem(i);
			int quantity = store_item.getQuantity();
			Coin coin = (Coin) store_item.getContent();
			if (quantity > 0) {
				// Check quantity of denomination required to give change
				int value = coin.getValue();
				int first = change / value; // Required quantity of denomination

				if (first > 0) {

					// If required quantity is not enough, just give all
					// quantity of denomination
					if (first > quantity)
						first = quantity;

					try {
						// Give Change
						//Iterator
						int i=cashstore.findCashStoreIndex(coin);
						
						tCtrl.getMainController().getMachineryController()
								.giveChange(i, first);

						// Update the change
						change = change - (value * first);

						// No more amount left to give change
						if (change == 0)
							break;
					} catch (VMCSException e) {
						System.out.println(e.getMessage());
						break;
					}
				}
			}
		}
		// If there is still an amount to give change after checking every
		// denomination,
		// it indicate we cannot give change full amount.
		change_available = (change == 0) ? true : false;

		// Update the displays on customer panel
		tCtrl.getCustomerPanel().getNoChangeDisplay().setState(
				!change_available);
		tCtrl.getCustomerPanel().getCollectCoinDisplay().setValue(
				change_required - change);

		return change_available;
	}

	/*
	 * Old code public boolean giveChange(int change_required){ Boolean
	 * change_available=false; Integer change=0;//change_required; CashStore
	 * cashstore=
	 * (CashStore)tCtrl.getMainController().getStoreController().getStore(Store.CASH);
	 * 
	 * int len=cashstore.getStoreSize(); for(int i=(len-1);i>=0;i--){
	 * CashStoreItem store_item=(CashStoreItem)cashstore.getStoreItem(i); int
	 * quantity=store_item.getQuantity(); Coin
	 * coin=(Coin)store_item.getContent(); //int value=coin.getValue(); int
	 * value=coin.getValue(); int first=change_required/value; int
	 * remainder=change_required%value;
	 * 
	 * if(first>quantity) first=0;
	 * 
	 * if(first>0){ if(first<=quantity) try{
	 * change_required=change_required-(value*first);
	 * tCtrl.getMainController().getMachineryController().giveChange(i,first);
	 * change=change+first*value; } catch(VMCSException e){ change_available=
	 * false; break; } }
	 * 
	 * else { remainder=change_required-value*quantity; if (remainder>0 &&
	 * quantity>0) { try{ change_required=remainder;
	 * tCtrl.getMainController().getMachineryController().giveChange(i,quantity);
	 * change=change+quantity*value; } catch(VMCSException e){ change_available=
	 * false; break; }
	 *  } } if (remainder==0) { change_available=true; break; }
	 * if(i==0&&remainder!=0) { change_available=false; break; } }
	 * if(change_available) {
	 * tCtrl.getCustomerPanel().getCollectCoinDisplay().setValue(change);
	 * tCtrl.getCustomerPanel().getNoChangeDisplay().setState(false); } //Else,
	 * turn on "NoChangeAvailable" else {
	 * tCtrl.getCustomerPanel().getCollectCoinDisplay().setValue(change);
	 * tCtrl.getCustomerPanel().getNoChangeDisplay().setState(true); } return
	 * change_available; }
	 */

	public void resetChange() {
		CustomerPanel custPanel = tCtrl.getCustomerPanel();
		LabelledDisplay lblDisplay = custPanel.getCollectCoinDisplay();
		lblDisplay.setValue("");
	}
}
